﻿//#define _CRT_SECURE_NO_WARNINGS
//#include <stdio.h>
//#include <string.h>

#include "common.h"

float max_two_num(float a, float b)
{
	return a > b ? a : b;
}

float max_all_num(float* arr, int size)
{ // 数组的前面size个元素的最大值
	float max = arr[0];
	int i;
	for (i = 1; i <= size; ++i)
		if (arr[i] > max)
			max = arr[i];
	return max;
}

void print_multiplication_table(int num)
{ // 打印到 num 的乘法表
	int i, j;
	for (i = 1; i <= num; ++i)
	{
		for (j = 1; j <= i; ++j)
			printf("%d x %d = %-5d ", j, i, i * j);
		printf("\n");
	}
}

int factorial(int n)
{ // 计算 n 的阶乘，递归实现，不考虑栈溢出
	return n <= 1 ? 1 : n * factorial(n - 1);
}

void factorial_array(int n)
{	// 计算 1 到 n 的阶乘，并打印
	int i;
	for (i = 1; i <= n; ++i)
		printf("%d! = %d\n", i, factorial(i));
}

int strlen_test1(const char* str)
{ // strlen 函数测试，非递归版本，时间复杂度 O(n)
	int len = 0;
	while (str[len] != '\0')
		++len;
	return len;
}

int strlen_test2(char* str)
{ // strlen 函数测试，递归版本
	char* p = str;
	return *p == '\0' ? 0 : 1 + strlen_test2(p + 1);
}

void reverse_str1(char* str)
{ // 字符串反转，循环实现，不使用标准库函数
	int index = 0;
	while (*(str + index) != '\0')
		++index;
	--index; // 指针指向字符串的末尾，
	// 因为上面循环完了之后 *(str + index) == '\0' 所以需要再减一
	char temp;
	int i, j = index;
	for (i = 0; i <= index / 2; ++i)
	{
		printf("i = %d, j = %d\n", i, j);
		temp = *(str + i);
		*(str + i) = *(str + j);
		*(str + j) = temp;
		--j;
	}
}

int reverse_str2(char str[], int start, int end) // 三个参数
{ // 字符串反转，递归实现，不使用标准库函数
	if (start >= end)
		return 0; // 递归终止条件，也可以反过来写为递归进入条件
	char temp = *(str + start);
	*(str + start) = *(str + end);
	*(str + end) = temp;
	return reverse_str2(str, start + 1, end - 1);
}

void reverse_str3(char* str) // 只有一个参数
{ // 字符串反转，递归实现，不用标准库函数（自己写的字符串长度函数效率上不如库函数）
	int len = strlen_test1(str); // 字符串长度，不包括 '\0'
	char temp = *str; // 保存首尾元素值
	*str = *(str + len - 1); // 首元素位置存放尾元素位置的值
	*(str + len - 1) = '\0'; // 截断字符串，为了递归调用
	if (strlen_test1(str + 1) >= 2)
		// 进入递归的条件，当前位置开始往后一位长度大于 1
		reverse_str3(str + 1); // 递归调用
	*(str + len - 1) = temp; // 尾元素位置存放原首元素位置的值
}

int digit_sum(unsigned int num)
{ // 计算整数的各位数字之和，递归实现
	if (num < 10)
		return num;
	else
		return num % 10 + digit_sum(num / 10);
}

int power_int(int n, int k)
{ // 计算整数 n 的整数 k 次方，递归实现
	if (k == 0)
		return 1;
	else if (k % 2 == 0)
		return power_int(n * n, k / 2);
	else
		return n * power_int(n * n, k / 2);
	// 奇数次方，n^k = n * n^(k/2) * n^(k/2)
}

double power_double(double n, int k)
{ // 计算浮点数 n 的整数 k 次方，递归实现
	if (0 == k)
		return 1.0;
	else if (0 < k)
		return n * power_double(n, k - 1);
	else // k < 0
		return 1.0 / power_double(n, -k);
	// 负数次方，n^k = 1 / n^(-k)
}
